/*
As3 Performances Analyzer
Copyright (C) 2011 Ankama Studio

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

Contact : seyraud@ankama.com
Project : http://code.google.com/p/as3-performances-analyzer
*/

package ui.components
{
	import flash.display.DisplayObject;
	import flash.display.LineScaleMode;
	import flash.events.Event;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.utils.Dictionary;
	
	import interfaces.ITimelineData;
	
	import mx.core.UIComponent;
	
	import spark.core.SpriteVisualElement;
	
	import types.Frame;
	
	public class GraphBarContainer extends UIComponent
	{
		//://///////////////////////////////////////////////////////////////
		//:// Variables privées
		//://///////////////////////////////////////////////////////////////
		
		private var _series : Array = [];
		private var _graphs : Dictionary = new Dictionary;
		private var _axeContainer : SpriteVisualElement = new SpriteVisualElement;
		private var _graphContainer : SpriteVisualElement = new SpriteVisualElement;
		
		private var _margeIn : uint = 20;
		private var _timestampOffset : Number = 0;
		
		private var _xScale : Number = 1;
		private var _drawAxe : Boolean = true;
		private var __height : Number = _margeIn;
		
		//://///////////////////////////////////////////////////////////////
		//:// Fonctions publiques
		//://///////////////////////////////////////////////////////////////
		
		public function GraphBarContainer()
		{
			addChild(_axeContainer);
			addChild(_graphContainer);
		}
		
		[Bindable]
		public override function get height():Number
		{
			return __height;
		}
		
		public override function set height(v:Number):void
		{
		}
		
		public function get drawAxe():Boolean
		{
			return _drawAxe;
		}

		public function set drawAxe(value:Boolean):void
		{
			_drawAxe = value;
			renderAxe();
		}
		
		public function set timestampOffset(v : Number) : void
		{
			_timestampOffset = v;
			renderAxe();
		}
		
		public function addSerie(frames : Vector.<ITimelineData>, id : String) : void
		{
			if(_graphs[id]) return;
			
			var g : GraphBar = new GraphBar(frames, this);
			g.graphId = id;
			g.addEventListener(Event.COMPLETE, onRenderEnd);
			g.x = _margeIn;
			_graphs[id] = g;
			_graphContainer.addChild(g);
			if(width < g.width + 2*_margeIn) width = g.width + 2*_margeIn;
		}
		
		public function removeSerie(targetId : String) : void
		{
			__height = _margeIn;
			for(var id : String in _graphs)
			{
				var g : GraphBar =  _graphs[id];
				if(g.graphId == targetId)
				{
					if(_graphContainer.contains(g))
						_graphContainer.removeChild(g);
					g.destroy();
					delete _graphs[id];
				}else
					if(__height < g.height + _margeIn)
						__height = g.height + _margeIn;
			}
			
			setActualSize(width, height);
			invalidateDisplayList();
			invalidateParentSizeAndDisplayList();
		}
		
		private function onRenderEnd(e:Event) : void
		{
			if(__height < e.target.height + _margeIn)
			{
				__height = e.target.height + _margeIn;
				setActualSize(width, height);
				invalidateDisplayList();
				invalidateParentSizeAndDisplayList();
			}
		}
		
		/** Mise à jour de la taille du composant */
		public override function setActualSize(w:Number, h:Number):void
		{
			super.setActualSize(w,h);
			renderAxe();
		}
		
		private function renderAxe() : void
		{
			while(_axeContainer.numChildren)
				_axeContainer.removeChildAt(0);
			_axeContainer.graphics.clear();
			
			if(!_drawAxe) return;
			
			_axeContainer.graphics.lineStyle(1,0xBBBBBB, 1.0, false, LineScaleMode.NONE);
			_axeContainer.graphics.moveTo(_margeIn, _margeIn);
			_axeContainer.graphics.lineTo(_margeIn, height - _margeIn);
			_axeContainer.graphics.lineTo(width - _margeIn, height - _margeIn);
			
			var origineX : uint = _margeIn;
			var origineY : uint = height - _margeIn;
			
			// Draw Y axe
			for(var y : int = origineY; y > _margeIn; y -= 31)
			{
				_axeContainer.graphics.lineStyle(1,0xBBBBBB, 1.0, false, LineScaleMode.NONE);
				_axeContainer.graphics.moveTo(origineX - 1, y);
				_axeContainer.graphics.lineTo(origineX + 3, y);
				if(y != origineY)
				{
					_axeContainer.graphics.lineStyle(1,0xEEEEEE, 1.0, false, LineScaleMode.NONE);
					_axeContainer.graphics.lineTo(width - _margeIn, y);
				}
			}
			
			// Draw X axe
			var tf : TextFormat = new TextFormat("Verdana", "10", 0xAAAAAA);
			var xValue : Number = 0;
			var display : Boolean;
			for(var x : int = origineX; x < width - origineX; x += 50)
			{
				_axeContainer.graphics.lineStyle(1,0x999999, 1.0, false, LineScaleMode.NONE);
				_axeContainer.graphics.moveTo(x, origineY + 2);
				_axeContainer.graphics.lineTo(x, origineY - 3);
				if(display)
				{
					var formatedXValue : String;
					var tmp : Number = xValue;
					var h : uint, m : uint,s : uint;
					if(_timestampOffset)
					{
						var d : Date = new Date();
						d.setTime(_timestampOffset + xValue);
						h = d.hours;
						m = d.minutes;
						s = d.seconds;
						
						formatedXValue = (m > 9 ? m+"" : "0" + m);
						formatedXValue = (h > 9 ? h+"" : "0" + h) + ":" + formatedXValue;
					}else{
						h = Math.floor(tmp / (1000 * 60 * 60));
						m = Math.floor((tmp - h * 1000 * 60 * 60) / (1000 * 60));
						s = Math.floor((tmp - h * 1000 * 60 * 60 - m * 1000 * 60) / 1000);
						
						formatedXValue = s > 9 ? s + "" : "0" + s;
						formatedXValue = (m > 9 ? m : "0" + m) + ":" + formatedXValue;
						if(h)
							formatedXValue = (h > 9 ? h : "0" + h) + ":" + formatedXValue;
					}
					
					
					var xLegend : TextField = new TextField;
					xLegend.defaultTextFormat = tf;
					xLegend.text = formatedXValue+"";
					xLegend.x = x - xLegend.textWidth / 2;
					xLegend.y = origineY + 3;
					xLegend.selectable = false;
					
					_axeContainer.addChild(xLegend);
				}
				display = !display;
				xValue += 1 / _xScale * 50;
				
			}
		}
	}
}